﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GraphosData
{
    public class Graph
    {
        // NOTE: temporary testing method. Should only take in a Person for final run
        //public Node AddNodeTemp(string name)
        //{
        //    Person person = new Person();
        //    person.FirstName = name;
        //    return AddNode(person);
        //}

        //// NOTE: temporary testing method. Should only take in a Person for final run
        //public void AddEdgeTemp(string name1, string name2)
        //{
        //    Node n1 = m_personToNode[name1];
        //    Node n2 = m_personToNode[name2];
        //    AddEdge(n1, n2, Relation.Unknown);
        //}

        public IEnumerable<Node> Nodes
        {
            get { return m_personToNode.Values; }
        }
        public Node GetNode(string id)
        {
            Node node;
            m_personToNode.TryGetValue(id, out node);
            return node;
        }
        public Node AddNode(Person person)
        {
            Node node;
            //if (!m_personToNode.TryGetValue(person.FirstName, out node))
            if (!m_personToNode.TryGetValue(person.ID, out node))
			{
                node = new Node(person);
                m_personToNode.Add(person.ID, node);
                //m_personToNode.Add(person.FirstName, node);
			}
            return node;
        }
		public Node AddNode(Node node)
		{
			//if (!m_personToNode.TryGetValue(node.Person, out node))
			m_personToNode.Add(node.Person.ID, node);
			return node;
		}
        public void AddEdge(string id1, string id2)
        {
            string p1 = m_personToNode.Keys.First(p => p == id1);
            string p2 = m_personToNode.Keys.FirstOrDefault(p => p == id2);
            AddEdge(p1, p2, Relation.Unknown);

        }
        public void AddEdge(string p1, string p2, Relation relation)
        {
            AddEdge(GetNode(p1), GetNode(p2), relation);
        }
        public void AddEdge(Node n1, Node n2, Relation relation)
        {
            if (n1 == null || n2 == null)
                return;

            n1.AddEdge(n2, relation);
        }
        SortedDictionary<string, Node> m_personToNode = new SortedDictionary<string, Node>();
    }

    public class Node
    {
        public Node(Person person)
        {
            m_person = person;
        }
        public Person Person
        {
            get { return m_person; }
        }
        //public IEnumerable<Edge> Edges
        //{
        //    get { return m_edges; }
        //}
        public IEnumerable<Node> AdjacentNodes
        {
            get { return m_nodeToRelation.Keys; }
        }
        public Relation RelationTo(Node node)
        {
            Relation rel;
            if (!m_nodeToRelation.TryGetValue(node, out rel))
                return Relation.Unknown;
            return rel;
        }
        public void AddEdge(Node node, Relation relation)
        {
            //m_edges.Add(new Edge(node, relation));
            m_nodeToRelation[node] = relation;
        }
        public override string ToString()
        {
            return string.Format("Node - {0}", Person);
        }
        private Person m_person;

        private Dictionary<Node, Relation> m_nodeToRelation = new Dictionary<Node, Relation>();
        private List<Edge> m_edges = new List<Edge>();
    }

    public class Edge
    {
        public Edge(Node node, Relation relation)
        {
            Node = node;
            Relation = relation;
        }

        public Node Node { get; set; }
        public Relation Relation { get; set; }
    }
}
